package org.song.util;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.song.model.entity.ApiEntity;
import org.song.model.entity.MenuEntity;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 该工具类是对数据库中的所有菜单按父子顺序进行排序
 */
public class TreeUtil {


    /**
     *
     * @param parentId 该参数是需要设置指定的 id 为父菜单
     * @param menusAll  传入的查询出来的数据库中的所有的菜单集合
     * @param array     传入一个JSONArray集合 用来接收排序之后的菜单
     */
    public static void setMenuEntityTree(Long parentId, List<MenuEntity> menusAll, JSONArray array) {
        //遍历所有的菜单
        for (MenuEntity per : menusAll) {
            //如果当前遍历出来的菜单的父id 等于传入的 父id，将当前对象转为JSON字符串，再转为对象 存入形参的父菜单的数组中去
            if (per.getPid().equals(parentId)) {
                String string = JSONObject.toJSONString(per);
                JSONObject parent = (JSONObject) JSONObject.parse(string);
                array.add(parent);
                if (menusAll.stream().anyMatch(p -> p.getPid().equals(per.getId()))) {
                    JSONArray child = new JSONArray();
                    parent.put("child", child);
                    //递归调用
                    setMenuEntityTree(per.getId(), menusAll, child);
                }
            }
        }
    }


    /**
     *
     * @param list 传入需要排序的菜单集合，按指定规则进行排序
     * @return 将排序好的菜单进行返回
     */
    //解析所有菜单
    public static List<MenuEntity> parseMenuTree(Iterable<MenuEntity> list){
        List<MenuEntity> result = new ArrayList<MenuEntity>();
        // 1、获取第一级节点
        for (MenuEntity menu : list) {
            //以下的方法写死了, 实际开发中 条件的判断取出 父级菜单的话 一般都是前端接收！！
            if(0L == menu.getId()) {
                result.add(menu);
            }
        }
        // 2、递归获取子节点
        for (MenuEntity parent : result) {
            parent = recursiveTree(parent, list);
        }
        return result;
    }


    /**
     * 该方法是遍历取出指定父菜单下的子菜单并且存入
     * @param parent 传入的单个父菜单对象
     * @param list   总的所有菜单
     * @return       返回值为从列表中取出符合条件的子菜单存入children属性中，并返回
     */
    //该方法是传入一个父菜单对象 将集合中的所有的子菜单存入
    public static MenuEntity recursiveTree(MenuEntity parent, Iterable<MenuEntity> list) {
        List<MenuEntity>children = new ArrayList<>();
        for (MenuEntity menu : list) {
            if (Objects.equals(parent.getId(), menu.getPid())) {
                children.add(menu);
            }
            parent.setChildren(children);
        }
        return parent;
    }


    /**
     *
     * @param list 传入需要排序的菜单集合，按指定规则进行排序
     * @return 将排序好的菜单进行返回
     */
    //解析所有菜单
    public static List<ApiEntity> parseApiMenuTree(List<ApiEntity> list){
        List<ApiEntity> result = new ArrayList<ApiEntity>();
        // 1、获取第一级节点
        for (ApiEntity api : list) {
            //以下的方法写死了, 实际开发中 条件的判断取出 父级菜单的话 一般都是前端接收！！
            if( 0L == api.getPid() ) {
                result.add(api);
            }
        }
        // 2、递归获取子节点
        for (ApiEntity parent : result) {
            parent = recursiveApiTree(parent, list);
        }
        return result;
    }


    /**
     * 该方法是遍历取出指定父菜单下的子菜单并且存入
     * @param parent 传入的单个父菜单对象
     * @param list   总的所有菜单
     * @return       返回值为从列表中取出符合条件的子菜单存入children属性中，并返回
     */
    //该方法是传入一个父菜单对象 将集合中的所有的子菜单存入
    public static ApiEntity recursiveApiTree(ApiEntity parent, List<ApiEntity> list) {
        List<ApiEntity> children = new ArrayList<>();
        for (ApiEntity api : list) {
            if (parent.getId().equals(api.getPid())) {
                children.add(api);
            }
            parent.setChildren(children);
        }
        return parent;
    }


}
